package net.zoneland.knowledge.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.constant.SdkConstant;
import net.zoneland.knowledge.exceptions.WorkSharedEditingException;
import net.zoneland.knowledge.model.*;
import net.zoneland.knowledge.service.*;
import net.zoneland.knowledge.utils.LoginUtils;
import net.zoneland.oadocs.sdk.pojo.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 附件在线编辑.
 */
@RestController
@RequestMapping("/sharedEditingOnline")
public class AttachmentOnlineEditController {

    private static final Logger LOGGER = LoggerFactory.getLogger(AttachmentOnlineEditController.class);

    /**
     * json工具类.
     */
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * od服务接口.
     */
    @Autowired
    private OaDocsSdkService oaDocsSdkService;

    /**
     * 智办工单业务接口
     */
    @Autowired
    private WorkApplyInfoService workApplyInfoService;

    /**
     * 创建并上传文件,同时将wps返回的fileId存到文件表.
     * @param request 请求
     * @param workApplyInfo 工单信息.
     * @return 创建结果
     */
    @PostMapping(value = "/createAndUploadFile")
    public ResponseResult createAndUploadFile(final HttpServletRequest request, @RequestParam(SdkConstant.WORK_APPLY_INFO_NAME) final String workApplyInfo) {
        final ResponseResult result = new ResponseResult();
        try {
            final LoginUserPojo user = checkCurrentUser(request);
            checkAndActiveUser(user);
            final WorkApplyInfo info = objectMapper.readValue(workApplyInfo, WorkApplyInfo.class);
            //校验数据
            checkData(info);
            oaDocsSdkService.initWorkApplyInfoTemplateAttachments(request, info, user);
            //过滤 是否已开启共享编辑,并且模板附件存在的数据
            workApplyInfoService.uploadSharedEditingAttachment(info);
        } catch (final JsonProcessingException e) {
            result.setResult(SdkConstant.FAIL);
            result.setMessage("创建并上传文件异常！异常信息:" + e.getMessage() +",workApplyInfo is " + workApplyInfo);
            LOGGER.error("创建并上传文件异常, workApplyInfo is {}", workApplyInfo, e);
        }
        return result;
    }

    /**
     * 激活用户.
     * @param user 当前登录用户信息.
     */
    private void checkAndActiveUser(final LoginUserPojo user) {
        oaDocsSdkService.activeAccountBatch(Arrays.asList(user.getUserID()));
    }

    /**
     * 数据校验.
     * @param workApplyInfo 工单信息
     */
    private void checkData(final WorkApplyInfo workApplyInfo) {
        Optional.ofNullable(workApplyInfo)
                .orElseThrow(() -> new WorkSharedEditingException("任务信息不能为空,工单信息:" + workApplyInfo));
        Optional.ofNullable(workApplyInfo.getSubTasks())
                .filter(CollectionUtils::isNotEmpty)
                .orElseThrow(() -> new WorkSharedEditingException("分任务列表不能为空,工单信息:" + workApplyInfo));
    }

    /**
     * 获取并校验当前用户.
     * @param request http请求
     * @return 当前用户
     */
    private LoginUserPojo checkCurrentUser(final HttpServletRequest request) {
        final LoginUserPojo user = LoginUtils.getCurrentUserByToken(request.getHeader(Constants.TOKEN_NAME));
        Assert.notNull(user, "用户未登录或登录信息不存在");
        return user;
    }

    /**
     * 在线编辑.
     * @param request
     * @param id 文件id.
     * @return 返回在线编辑的url
     */
    @RequestMapping(value = "/onlineEdit", method = RequestMethod.GET)
    public ResponseResult onlineEdit(final HttpServletRequest request, final String id) {
        final LoginUserPojo user = checkCurrentUser(request);
        checkAndActiveUser(user);
        //查询在线编辑客户端链接
        final DocResult<String> docResult = oaDocsSdkService.queryOnlineEditClientLink(user.getUserID(), id);
        return docResult.getCode() == SdkConstant.SUCCESS ?
                new ResponseResult(docResult.getData()) : new ResponseResult();
    }


    /**
     * 下载文件.
     * @param id 附件ID
     * @returnn 返回可以url点击直接下载，有效期一小时，失效要重新获取
     */
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public ResponseResult downloadFile(final HttpServletRequest request, final String id) {
       final LoginUserPojo user = checkCurrentUser(request);
        checkAndActiveUser(user);
        final DocResult<String> docResult = oaDocsSdkService.queryDownloadLink(id);
        return docResult.getCode() == SdkConstant.SUCCESS ?
                new ResponseResult(docResult.getData()) : new ResponseResult();
    }

}
